package com.hunter.desktop.file.fetch.support;

import java.io.File;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import com.hunter.desktop.file.fetch.Chooser;
import com.hunter.desktop.file.fetch.support.ChooserClause.Occur;

/**
 * 将选择器分成组，一个组内的选择器内部，同时拥有它们各自的关系.
 * 
 * @author bastengao
 * 
 */
public class ChooserGroup implements Chooser {

	private List<ChooserClause> clauses = new LinkedList<ChooserClause>();

	public ChooserGroup() {
	}

	public ChooserGroup(List<ChooserClause> clauses) {
		this.clauses.addAll(clauses);
	}

	public ChooserGroup(ChooserClause clause, ChooserClause... clauses) {
		this.clauses.add(clause);
		this.clauses.addAll(Arrays.asList(clauses));
	}

	public void add(ChooserClause clause) {
		clauses.add(clause);
	}

	/**
	 * 按Clause的加入顺序,依次调用 Clause 提供的Chooser 进行判断。
	 * <p>
	 * 有如下规则：
	 * <ol>
	 * <li>如果 Clause 的 Occur 为 SHOULD ,chooser 返回 true，则立即返回 true;否则进行下一个 Clause
	 * 判断</li>
	 * <li>如果 Clause 的 Occur 为 NOT 或者 为 MUST ,chooser 返回 false，则立即返回 false(即快速失败)，否则进行下一个Clause</li>
	 * <li>如果有下一个进行以上两次过程，直至结束</li>
	 * </ol>
	 */
	@Override
	public boolean accept(File file) {
		boolean flag = false;
		for (ChooserClause clause : clauses) {
			boolean isAccepted = clause.getChooser().accept(file);
			if (clause.getOccur() == Occur.SHOULD) {
				if (isAccepted) {
					// 如果 或为真，则必为真
					return true;
				}
				// 且 和 非， 都是快速失败的，只要有一个是假，则立即返回 false,如果为真，则置flag 为 真
			} else if (clause.getOccur() == Occur.MUST) {
				if (!isAccepted) {
					return false;
				} else {
					flag = true;
				}
			} else if (clause.getOccur() == Occur.NOT) {
				isAccepted = !isAccepted;
				if (!isAccepted) {
					return false;
				} else {
					flag = true;
				}
			}
		}
		return flag;
	}

}
